//
//  Reciever.cpp
//  UDPReciever
//
//  Created by Thomas Van Winckel on 25/02/15.
//  Copyright (c) 2015 Thomas Van Winckel. All rights reserved.
//

#include "Reciever.h"
//#define DEBUG 1

Info Reciever::recieve(){
    struct Udp_package incommingData;
    struct Info robotData;

    #ifdef DEBUG
    std::cout << "Trying to create or connect the socket...\n" << endl;
	#endif

    /*
        initConnection() tracht een verbinding tot stand te brengen.
        Indien er geen socket gecreeerd kan worden, wordt de error "NOSOCKET" teruggegeven.
        Indien het socket niet gebonden kan worden, wordt de error "NOCONNECTION teruggegeven.
    */

    int error = initConnection();

    if(error > 0)
    {
        printConnectionError(error);
    }
	else
	{
		std::cout << "Connection opened." << endl;
	}
    int i = 0;

    i++;
    incommingData = run();
    robotData = incommingData.info_a;

	//#ifdef DEBUG
        std::cout << i << "robot: x=" << robotData.robx << ", y=" << robotData.roby << ", a=" << robotData.robhoek << endl;
        std::cout << i << "blik: x=" << robotData.doelx << ", y=" << robotData.doely << endl;
        std::cout << i << "gar: x=" << robotData.garx << ", y=" << robotData.gary << endl;
    //#endif
    /* Pas een delay van 1s toe op het ontvangen van data -> Testdoeleinde. */

    return robotData;
}

int Reciever::initConnection()
{
    myAddr.sin_family = AF_INET;
    myAddr.sin_addr.s_addr = htonl(INADDR_ANY);
    myAddr.sin_port = htons(UDPPORT);

    #ifdef DEBUG
        std::cout << "Connecting..." << endl;
	#endif

    if((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
    {
        return NOSOCKET;
    }

    if( ::bind(sock, (struct sockaddr* ) &myAddr, (int)sizeof(myAddr)) == -1)
    {
        return NOCONNECTION;
    }

    return 1;
}

Udp_package Reciever::run()
{
    #ifdef DEBUG
        std::cout << "Trying to catch a package..." << endl;
	#endif

    socklen_t sockLen = sizeof(otherAddr);

    /*
         Data "inbuf" komt binnen. Inbuf is een struct van het type "Udp_package", deze struct bevat (2) andere
         structs van het type "Info" één voor elke robot. Wij gebruiken enkel die van onze robot (A).
    */

    long boodschap = recvfrom(sock, &inbuf, INBUFLEN, 0, (struct sockaddr*) &otherAddr, &sockLen);

    #ifdef DEBUG
        std::cout << "Recvfrom return value: " << boodschap << endl;
	#endif

    /*
		Testprint van robotA data in de UDP run functie.
		int groepA = inbuf.groep_a;
		struct Info infoA = inbuf.info_a;
		cout << "GroepA = " << groepA << endl;
		cout << "Robot positie: "<< infoA.robx << " ," << infoA.roby << endl;
    */

    Reciever::closeConnection();
    return inbuf;
}

void Reciever::closeConnection()
{
    close(sock);
    cout << "Connection closed." << endl;
}


void Reciever::printConnectionError(int error)
{
    switch(error)
    {
        case NOSOCKET:
            cout << "No socket was created." << endl;
            break;
        case NOCONNECTION:
            cout << "Could not bind the socket." << endl;
            break;
    }
}

